package com.dycx.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dycx.common.ResourceFileUtil;
import com.dycx.system.converter.PermissionConverter;
import com.dycx.system.dto.PermissionDTO;
import com.dycx.system.entity.PermissionDO;
import com.dycx.system.mapper.PermissionMapper;
import com.dycx.system.service.PermissionService;
import com.dycx.system.vo.ActionVO;
import com.dycx.system.vo.PermissionVO;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;


@Service
@AllArgsConstructor
public class PermissionImpl extends ServiceImpl<PermissionMapper, PermissionDO> implements PermissionService {

    private final StringRedisTemplate stringRedisTemplate;


    private static final String ALL_PERMISSION_KEY = "AllPermissionKey:";


    /**
     * 查询所有操作权限
     *
     * @return
     */
    @Override
    public void batchAdd() {
        String jsonStr = ResourceFileUtil.readJsonFile("role_action.json");
        List<ActionVO> list = JSON.parseArray(jsonStr, ActionVO.class);
        batchAdd(list, 0);
    }

    private void batchAdd(List<ActionVO> voList, Integer parentId) {
        voList.forEach(item -> {
            PermissionDO entity = new PermissionDO();
            entity.setParentId(parentId);
            entity.setPermissionId(item.getId());
            entity.setTitle(item.getName());
            entity.setRouter(item.getRouter());
            save(entity);
            if (ObjectUtil.isNotEmpty(item.getChildren()) && item.getChildren().size() > 0) {
                batchAdd(item.getChildren(), entity.getId());
            }
        });
    }


    @Override
    public Boolean delete(Integer id) {
        if(!this.removeById(id)) throw new RuntimeException("删除失败");
        updateCache();
        return true;
    }

    public PermissionVO getByPermissionId(String permissionId) {
        LambdaQueryWrapper<PermissionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PermissionDO::getPermissionId, permissionId);
        return PermissionConverter.entityToVo(getOne(wrapper));
    }

    /**
     * 添加
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean add(PermissionDTO dto) {
        PermissionVO permissionVO = getByPermissionId(dto.getPermissionId());
        if (ObjectUtil.isNotEmpty(permissionVO)) throw new RuntimeException("权限ID已存在，请重新输入");

        PermissionDO entity = BeanUtil.toBean(dto, PermissionDO.class);
        if(!save(entity)) throw new RuntimeException("添加失败");
        dto.setId(entity.getId());

        updateCache();
        return true;
    }

    /**
     * 修改
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean edit(PermissionDTO dto) {
        LambdaQueryWrapper<PermissionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PermissionDO::getPermissionId, dto.getPermissionId());
        wrapper.ne(PermissionDO::getId, dto.getId());

        if (ObjectUtil.isNotEmpty(getOne(wrapper))) {
            throw new RuntimeException("权限ID已存在，请重新输入");
        }

        PermissionDO entity = BeanUtil.toBean(dto, PermissionDO.class);
        if(!this.updateById(entity)) throw new RuntimeException("保存失败");
        updateCache();
        return true;
    }

    /**
     * 获取父类下的所有分类
     *
     * @return
     */
    @Override
    public List<PermissionVO> getAllList() {
        String redisSystemConfigStr = stringRedisTemplate.opsForValue().get(ALL_PERMISSION_KEY);
        if (StrUtil.isNotBlank(redisSystemConfigStr)) {
            return JSON.parseArray(redisSystemConfigStr, PermissionVO.class);
        }

        List<PermissionVO> res = getAllList(0, true);
        stringRedisTemplate.opsForValue().set(ALL_PERMISSION_KEY, JSON.toJSONString(res));
        return res;
    }

    public void updateCache(){
        stringRedisTemplate.delete(ALL_PERMISSION_KEY);
        getAllList();
    }

    @Override
    public List<PermissionVO> getAllList(Integer parentId, Boolean status) {
        LambdaQueryWrapper<PermissionDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PermissionDO::getParentId, parentId);
        queryWrapper.eq(ObjectUtil.isNotNull(status), PermissionDO::getStatus, status);
        queryWrapper.orderByDesc(PermissionDO::getSort);

        List<PermissionVO> voList = PermissionConverter.entityToVoList(this.list(queryWrapper));

        for (PermissionVO vo : voList) {
            List<PermissionVO> childrenList = getAllList(vo.getId(), status);
            if (ObjectUtil.isNotEmpty(childrenList)) {
                vo.setChildren(childrenList);
            }
        }

        return voList;
    }

    /**
     * 更新排序
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean updateSort(PermissionDTO dto) {
        PermissionDO entity = new PermissionDO();
        entity.setId(dto.getId());
        entity.setSort(dto.getSort());

        if(!this.updateById(entity)) throw new RuntimeException("保存失败");
        updateCache();
        return true;
    }

    /**
     * 更新状态
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean updateStatus(PermissionDTO dto) {
        PermissionDO entity = new PermissionDO();
        entity.setId(dto.getId());
        entity.setStatus(dto.getStatus());

        if(!this.updateById(entity)) throw new RuntimeException("保存失败");
        updateCache();
        return true;
    }


    /**
     * 查询父类下第一级分类
     *
     * @param parentId
     * @return
     */
    @Override
    public List<PermissionVO> getListByParentId(Integer parentId) {
        return getListByParentId(parentId, null);
    }

    @Override
    public List<PermissionVO> getListByParentId(Integer parentId, Boolean status) {
        LambdaQueryWrapper<PermissionDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PermissionDO::getParentId, parentId);
        queryWrapper.eq(ObjectUtil.isNotNull(status), PermissionDO::getStatus, status);
        queryWrapper.orderByDesc(PermissionDO::getSort);

        List<PermissionVO> voList = PermissionConverter.entityToVoList(this.list(queryWrapper));

        voList.forEach(item -> {
            //是否有子类
            LambdaQueryWrapper<PermissionDO> queryCount = new LambdaQueryWrapper<>();
            queryCount.eq(PermissionDO::getParentId, item.getId());
            queryCount.eq(ObjectUtil.isNotNull(status), PermissionDO::getStatus, status);
            item.setHasChildren(count(queryCount) > 0);
        });

        return voList;
    }

}
